import {userProfile} from "../../entity/UserProfile";
import {GAME_CONFIGS} from "./GameConfigs";

/**
 *  如果不需要matchvs 功能,请直接注释全文.
 */
declare const require: any;
const mvs = require("./matchvs/MatchvsExport");

import Context from "../../../framework/Context";
import {MatchResponse} from "./MatchResponse";
import {DataFactory, JsonDataFactory} from "./DataFactory";

class MatchAdapter {
    private readonly engine = mvs.engine;
    private readonly response = mvs.response;
    private responseNotifier: MatchResponse = null;
    private dataFactory: DataFactory = new JsonDataFactory();

    public setDataFactory(dF: DataFactory) {
        this.dataFactory = dF;
    }

    public openLog(open: boolean) {
        if (open) {
            MatchvsLog.openLog();
        } else {
            MatchvsLog.closeLog();
        }
    }

    public isInit(): boolean {
        return this.responseNotifier && this.responseNotifier.isInit;
    }

    public isLogin(): boolean {
        return this.responseNotifier && this.responseNotifier.isLogin;
    }

    // 初始化matchvs 引擎.
    public init(context: Context, dataFactory?: DataFactory): number {
        if (this.responseNotifier) {
            this.responseNotifier.unbind();
        }
        this.openLog(GAME_CONFIGS.DEBUG);

        this.responseNotifier = new MatchResponse(this.response, context);
        this.responseNotifier.bind();

        if (dataFactory) {
            this.dataFactory = dataFactory;
        }

        return this.engine.init(this.response, GAME_CONFIGS.channel, GAME_CONFIGS.platform,
            GAME_CONFIGS.gameId, GAME_CONFIGS.appkey, GAME_CONFIGS.gameVersion);
    }

    // 反注册，反注册后response 回调失效。
    public unint(): boolean {
        return 0 === this.engine.uninit();
    }

    public login(): number {
        return this.engine.login(userProfile.thirdInfo.userid, userProfile.thirdInfo.token, userProfile.thirdInfo.deviceid);
    }

    public logout(msg: any): number {
        return this.engine.logout(this.dataFactory.encode(msg));
    }

    public registerUser(): number {
        return this.engine.registerUser()
    }

    public joinRandomRoom(maxPlayer: number, userProfile: any): boolean {
        return 0 === this.engine.joinRandomRoom(maxPlayer, this.dataFactory.encode(userProfile));
    }

    public joinRoomWithProperties(matchinfo: MsMatchInfo, userProfile: any, watchSet?: MVS.MsWatchSet): number {
        return this.engine.joinRoomWithProperties(matchinfo, this.dataFactory.encode(userProfile), watchSet);
    }

    public createRoom(createRoomInfo: MsCreateRoomInfo, userProfile: any, watchSet?: MVS.MsWatchSet): number {
        return this.engine.createRoom(createRoomInfo, this.dataFactory.encode(userProfile), watchSet);
    }

    public leaveRoom(cpProto: any): number {
        return this.engine.leaveRoom(this.dataFactory.encode(cpProto));
    }

    public joinRoom(roomID: string, userProfile: any): number {
        return this.engine.joinRoom(roomID, this.dataFactory.encode(userProfile));
    }

    public getRoomListEx(filter: MsRoomFilterEx): number {
        return this.engine.getRoomListEx(filter);
    }

    public getRoomDetail(roomID: string): number {
        return this.engine.getRoomDetail(roomID);
    }

    public setRoomProperty(roomID: string, roomProperty: any): number {
        return this.engine.setRoomProperty(roomID, this.dataFactory.encode(roomProperty))
    }

    /**
     * result    number    错误码，0表示成功，其他表示失败    0
     * sequence    number    事件序号，作为事件的唯一标识。
     * 客户端发送消息后收到的sendEventResponse 也会收到 sequence 标识，通过此标识来确定这个sendEventResponse 是由哪次sendEvent 发送的。主要用于在游戏中做信息同步的时候，网络传输都有延迟会出现sendEvent与sendEventResponse 收到顺序不同。
     * @param data
     * @param isBinary
     */
    public sendEvent(data: object, isBinary: boolean = false): any {
        if (isBinary) {
            return this.engine.sendEvent(data, true);
        } else {
            return this.engine.sendEvent(this.dataFactory.encode(data), false);
        }
    }

    /**
     * msgType    number    消息发送类型：0表示转发给其他玩家；1表示转发给game server；2表示转发给其他玩家及game server    2
     data    string    发送内容    "hello"
     destType    number    发送目标类型：0表示发送目标为userIDs；1表示发送目标为除userIDs以外的房间其他人    0
     userIDs    Array    发送目标
     * @param msgType
     * @param data
     * @param destType
     * @param userIDs
     */
    public sendEventEx(msgType: number, data: string, destType: number, userIDs: Array<number>): any {
        return this.engine.sendEventEx(msgType, data, destType, userIDs);
    }

    public subscribeEventGroup(confirms: Array<string>, cancles: Array<string>): number {
        return this.engine.subscribeEventGroup(confirms, cancles);
    }

    public sendEventGroup(groups: Array<string>, data: any): number {
        return this.engine.sendEventGroup(groups, this.dataFactory.encode(data))
    }

    // 设置帧同步速率，发送帧同步消息之前一定要先设置帧同步。帧同步最大值为20。也就是 50ms 发送一次数据。
    public setFrameSync(frameRate: number, enableGS?: number, other?: any): number {
        return this.engine.setFrameSync(frameRate, enableGS, other)
    }

    public sendFrameEvent(cpProto: object, op?: number): number {
        return this.engine.sendFrameEvent(this.dataFactory.encode(cpProto), op, false);
    }

    public reconnect(): number {
        return this.engine.reconnect();
    }

    public setReconnectTimeout(timeout: number): number {
        return this.engine.setReconnectTimeout(timeout);
    }

    public getOffLineData(cacheFrameMS: number): number {
        return this.engine.getOffLineData(cacheFrameMS);
    }

    public joinOpen(data: any): number {
        return this.engine.joinOpen(this.dataFactory.encode(data));
    }

    public getWatchRoomList(filter: MsRoomFilterEx): number {
        return this.engine.getWatchRoomList(filter);
    }

    public joinWatchRoom(roomID: string, userProfile: any): number {
        return this.engine.joinWatchRoom(roomID, this.dataFactory.encode(userProfile))
    }

    public leaveWatchRoom(cpProto: object): number {
        return this.engine.leaveWatchRoom(this.dataFactory.encode(cpProto));
    }

    // 设置观战数据偏移位置，指定从哪里开始播放。
    public setLiveOffset(offsetMS: number): number {
        return this.engine.setLiveOffset(offsetMS);
    }

    /**
     * userProfile    string    附带消息，默认填空值    ""
     * rType    number    要转换的模式，0-切换到游戏模式，1-切换到观战模式，
     * 这是一个可选参数，如果不填该参数，接口会根据你当前处于什么模式自动转换。
     * @param userProfile
     * @param rType
     */
    public changeRole(userProfile: object, rType?: number): number {
        return this.engine.changeRole(this.dataFactory.encode(userProfile), rType);
    }

    public kickPlayer(userID: number, cpProto: object): number {
        return this.engine.kickPlayer(userID, this.dataFactory.encode(cpProto));
    }

    // 一般在匹配到用户，开始游戏之前要关闭房间，防止有其他玩家中途加入。
    public joinOver(cpProto: object): number {
        return this.engine.joinOver(this.dataFactory.encode(cpProto));
    }

    // 对响应的数据进行解码。
    public decode(data: string): any {
        return this.dataFactory.decode(data)
    }

    // 绑定平台供的帐号。
    public thirdBind() {

    }
}

export const M = new MatchAdapter();


